﻿/*!
 * @file grayscalethresh.cpp
 * @author 川西康友
 * @date Last Change: 2010/Apr/03.
 * */

#include "ImageBackgroundSubtractorGrayScaleThresh.h"
using namespace mmpl;
using namespace mmpl::image;
/** 
 * @brief コンストラクタ
 * @param bgimage 背景画像
 * @param threshold 閾値
 */
BackgroundSubtractorGrayScaleThresh::BackgroundSubtractorGrayScaleThresh(const Image& bgimage,int threshold)
	:bgimage(bgimage),threshold(threshold){
		this->bgimage.setChannels(1);
		isBGset=true;
	}

/** 
 * @brief コンストラクタ
 * @param bgname ファイル名
 * @param threshold 閾値
 */
BackgroundSubtractorGrayScaleThresh::BackgroundSubtractorGrayScaleThresh(const std::string& bgname,int threshold)
	:bgimage(bgname,CV_LOAD_IMAGE_GRAYSCALE),threshold(threshold){
		isBGset=true;
	}

BackgroundSubtractorGrayScaleThresh::BackgroundSubtractorGrayScaleThresh(int threshold):threshold(threshold){
	isBGset=false;
}

/** 
 * @brief デストラクタ
 */
BackgroundSubtractorGrayScaleThresh::~BackgroundSubtractorGrayScaleThresh(){}

BackgroundSubtractorGrayScaleThresh* BackgroundSubtractorGrayScaleThresh::clone()const{
	return new BackgroundSubtractorGrayScaleThresh(*this);
}

bool BackgroundSubtractorGrayScaleThresh::equals(const BackgroundSubtractAlgorithm& other)const{
	if(this==&other){
		return true;
	}
	const BackgroundSubtractorGrayScaleThresh* bss=dynamic_cast<const BackgroundSubtractorGrayScaleThresh*>(&other);
	if(bss==0){
		return false;
	}
	if(bgimage==bss->getBGImage() && threshold==bss->getThreshold()){
		return true;
	}
	return false;
}

void BackgroundSubtractorGrayScaleThresh::print(std::ostream& out)const{
	out << "BackgroundSubtractorGrayScaleThresh(BG:" << bgimage;
	out << "Threshold:" << threshold << ")";
}

const Image& BackgroundSubtractorGrayScaleThresh::getBGImage()const{
	return bgimage;
}

void BackgroundSubtractorGrayScaleThresh::setBGImage(const Image& bgimage){
	this->bgimage=bgimage;
	this->bgimage.setChannels(1);
	isBGset=true;
}

void BackgroundSubtractorGrayScaleThresh::setBGImage(const std::string& bgfilename){
	this->bgimage.loadImage(bgfilename,CV_LOAD_IMAGE_GRAYSCALE);
	isBGset=true;
}

void BackgroundSubtractorGrayScaleThresh::setThreshold(int thresh){
	threshold=thresh;
}

int BackgroundSubtractorGrayScaleThresh::getThreshold()const{
	return threshold;
}

BackgroundSubtractorGrayScaleThresh::BackgroundSubtractorGrayScaleThresh(const BackgroundSubtractorGrayScaleThresh& other)
	:BackgroundSubtractAlgorithm(other),
	bgimage(other.getBGImage()),threshold(other.getThreshold()){
	}

/** 
 * @brief グレースケールでの背景差分
 * @param img 適用する画像
 * @param oimg 背景差分結果。予め背景色にする色を指定しておく
 */
void BackgroundSubtractorGrayScaleThresh::apply(const Image& img,BGSubtractedImage* oimg){
	if(!isBGset)return;
	if(img.getWidth()!=oimg->getWidth())oimg->setWidth(img.getWidth());
	if(img.getHeight()!=oimg->getHeight())oimg->setHeight(img.getHeight());
	if(oimg->getChannels()!=1)oimg->setChannels(1);
	Image temp(img);
	temp.setChannels(1);
	cvAbsDiff(temp.getIplImage(),bgimage.getIplImage(),temp.getIplImage());
	cvThreshold(temp.getIplImage(),oimg->getIplImage(),threshold,255,CV_THRESH_BINARY);
	oimg->setChannels(3);
	cvAnd(oimg->getIplImage(),img.getIplImage(),oimg->getIplImage());
	oimg->setBGColor(Color(0,0,0));
}
